﻿Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports System.IO
Imports System.ServiceModel
Imports Contracts
Imports Entities
Imports Albatross.ClientSide.WCF
Imports Albatross.Common.Exceptions
Imports System.ServiceModel.Channels
Imports System.Xml
Module Module1
  ' Here we define our client proxies that we use in the sample subs below
  ' Note that you can create an Albatross proxy directly out of the configuration (e.g. app.config) or through code
  ' Private configRequestProxy As New RequestProcessorProxyForDotNetClient()
  'Private progRequestProxy As RequestProcessorProxyForDotNetClient = GetRPProxyWithProgrammaticallyCreatedSettings()
  'Private progRequestProxy As RequestProcessorProxyForDotNetClient = GetRPProxyWithProgrammaticallyCreatedSettingsAndCompression()

  ' Using the ChannelFactoryProxy (config or code), another way to use Albatross but not the recommended way 
  'Private configProxy As Albatross.Common.WCF.IWcfRequestProcessor = GetServiceProxyWithConfigFileSettings()
  'Private progProxy As Albatross.Common.WCF.IWcfRequestProcessor = GetServiceProxyWithProgrammaticallyCreatedSettings()

  Private oRequestProcessorProxyForDotNetClient As Albatross.ClientSide.WCF.RequestProcessorProxyForDotNetClient

  Sub Main()
    ' A few sample functions that use the Albatross Framework
    ' Uncomment each sample function to try it out

    ' Using the RequestProcessorProxy (config or code)
    ' This is the recommended way to use Albatross for (non Silverlight) DotNet clients

    oRequestProcessorProxyForDotNetClient = GetRPProxyWithProgrammaticallyCreatedSettings()
    oRequestProcessorProxyForDotNetClient.ClientCredentials.UserName.UserName = "Bob"
    oRequestProcessorProxyForDotNetClient.ClientCredentials.UserName.Password = "*****"

		'Call RPGetBorrowerOneRequest()
		Call RPGetBorrowerOneRequestAsync()
		'Call RPGetImage()

    'Call RPProxyGetBorrowerOneRequestAsync()
    'Call RPGetBorrowerWithWrap()
    'Call RPGetBorrowerAndListBorrowersOneCallMultipleRequests()
    'Call RPGetBorrowerRaiseException()
    'Call RPGetBorrowerRaiseException2()

    ' Using the ChannelFactoryProxy (config or code)
    ' Another way to use Albatross, but not the recommended way (all samples may not be up to date)
    'Call GetBorrowerOneRequestConfigProxy()
    'Call GetBorrowerOneRequestCodeProxy()
    'Call GetBorrowerOneRequestWithStatusCode()
    'Call GetBorrowerRaiseException() ' Uncomment this line to see how you should handle exceptions on the client
    'Call GetBorrowerAndListBorrowersOneCallMultipleRequests()
    'Call RPGetLargeResponseRequest()

    Console.WriteLine()
    Console.WriteLine("Done! Press any key to end.")

    Console.ReadKey()
  End Sub



  ' -----------------------------------------
  ' ------- Create Proxy through code -------
  ' -----------------------------------------
  'Public Function GetRPProxyWithProgrammaticallyCreatedSettings() As RequestProcessorProxyForDotNetClient
  '  Dim binding = New BasicHttpBinding()
  '  Dim address = New EndpointAddress("http://localhost:9000/RequestProcessor.svc")
  '  Return New RequestProcessorProxyForDotNetClient(binding, address)
  'End Function

  'Public Function GetRPProxyWithProgrammaticallyCreatedSettingsAndCompression() As RequestProcessorProxyForDotNetClient
  '  Dim address = New EndpointAddress("http://localhost:9000/RequestProcessor.svc") ' 9001 for azure host
  '  Return New RequestProcessorProxyForDotNetClient("WcfRequestProcessor.EndPoint", address)
  'End Function

  Public Function GetRPProxyWithProgrammaticallyCreatedSettings() As Albatross.ClientSide.WCF.RequestProcessorProxyForDotNetClient
    Dim binding = New Albatross.WCF.Extenions.Bindings.ClearUsernameBinding()
    ' binding.SetMessageVersion( MessageVersion.Soap12 );

    Dim compression = New Albatross.WCF.Extenions.ServiceModel.Channels.CompressionBindingElement()
    compression.Algorithm = Albatross.WCF.Extenions.ServiceModel.Channels.CompressionAlgorithm.GZip
    compression.Level = Albatross.WCF.Extenions.ServiceModel.Channels.CompressionLevel.Normal

		'binding.ClearElement.Add(compression)

		Dim oTextMessageEncodingBindingElement As New TextMessageEncodingBindingElement()	' TextMessageEncodingBindingElement or MtomMessageEncodingBindingElement
    oTextMessageEncodingBindingElement.MessageVersion = MessageVersion.Soap12

    'Dim oXmlDictionaryReaderQuotas As New XmlDictionaryReaderQuotas()

    oTextMessageEncodingBindingElement.ReaderQuotas.MaxArrayLength = Integer.MaxValue
    oTextMessageEncodingBindingElement.ReaderQuotas.MaxBytesPerRead = Integer.MaxValue
    oTextMessageEncodingBindingElement.ReaderQuotas.MaxDepth = Integer.MaxValue
    oTextMessageEncodingBindingElement.ReaderQuotas.MaxNameTableCharCount = Integer.MaxValue
    oTextMessageEncodingBindingElement.ReaderQuotas.MaxStringContentLength = Integer.MaxValue

    binding.ClearElement.Add(oTextMessageEncodingBindingElement)
    binding.ClearElement.Add(SecurityBindingElement.CreateUserNameOverTransportBindingElement())

    ' -------------------
    ' - When using HTTP -
    ' -------------------
    binding.ClearElement.Add(New Albatross.WCF.Extenions.Bindings.AutoSecuredHttpTransportElement())

		Dim address = New EndpointAddress("http://127.0.0.1:9100/RequestProcessor.svc")	' WebHost (host: Casini)
		Console.WriteLine("In GetRPProxyWithProgrammaticallyCreatedSettings() - WebHost RP proxy on http://127.0.0.1:9100/RequestProcessor.svc")

		' If using Fiddler -
		'Dim address = New EndpointAddress("http://ipv4.fiddler:9000/RequestProcessor.svc") ' WebHost (host: Casini)
		'Console.WriteLine("In GetRPProxyWithProgrammaticallyCreatedSettings() - WebHost RP proxy on http://ipv4.fiddler:9000/RequestProcessor.svc")

    'Dim address = New EndpointAddress("http://127.0.0.1:9001/RequestProcessor.svc") ' AzureHost HTTP (host: Windows Azure local development fabric)
    'Console.WriteLine("In GetRPProxyWithProgrammaticallyCreatedSettings() - Albatross RP proxy on http://127.0.0.1:9001/RequestProcessor.svc")

    ' --------------------
    ' - When using HTTPS -
    ' --------------------
    ' binding.ClearElement.Add(New HttpsTransportBindingElement)

    ' Dim address = New EndpointAddress("https://127.0.0.1/RequestProcessor.svc") ' AzureHost HTTPS (host: Windows Azure local development fabric)
    ' Console.WriteLine("In GetRPProxyWithProgrammaticallyCreatedSettings() - Albatross RP proxy on https://127.0.0.1/RequestProcessor.svc")

    Console.WriteLine()

    Return New Albatross.ClientSide.WCF.RequestProcessorProxyForDotNetClient(binding, address)
  End Function

  ' -----------------------------------------
  ' ---------- Synchronous Call -------------
  ' -----------------------------------------
  Private Sub RPGetBorrowerOneRequest()
    Dim entityRequest = New GetBorrowerI()

    Console.WriteLine("Calling GetBorrower() based on programmatically created settings")
    Console.WriteLine()

    Dim response = DirectCast(oRequestProcessorProxyForDotNetClient.Process(entityRequest).First(), GetBorrowerO)

    Console.WriteLine("  First Name: " & response.MyBorrower.FirstName.ToString())
    Console.WriteLine("  Last Name: " & response.MyBorrower.LastName.ToString())
    Console.WriteLine("")
  End Sub

	' -----------------------------------------
	' ---------- Asynchronous Call ------------
	' -----------------------------------------
	Private Sub RPGetBorrowerOneRequestAsync()
		Dim entityRequest = New GetBorrowerI()

		Console.WriteLine("Calling GetBorrower() asynchronously based on programmatically created settings")

		oRequestProcessorProxyForDotNetClient.ProcessAsync(AddressOf RPGetBorrowerOneRequestAsyncCallBack, entityRequest)

		Console.WriteLine("Done with RPGetBorrowerOneRequestAsync()")
		Console.WriteLine()
	End Sub

	Private Sub RPGetBorrowerOneRequestAsyncCallBack(ByVal responses As IList(Of Albatross.Common.Messaging.Response))

		Console.WriteLine("In the call back - RPGetBorrowerOneRequestAsyncCallBack()")

		Dim response = DirectCast(responses(0), GetBorrowerO)

		Console.WriteLine("First Name: " & response.MyBorrower.FirstName.ToString())
		Console.WriteLine("Last Name: " & response.MyBorrower.LastName.ToString())
		Console.WriteLine("")
	End Sub

	Private Sub RPGetImage()
		Dim entityRequest = New GetImageI()
		Dim oFileStream As FileStream
		Dim cFILENAME As String = "C:\vss\AlbatrossFramework\Samples\VB\ConsoleClient\bin\Debug\project.jpg"

		Console.WriteLine("Calling GetImage()...")
		Console.WriteLine()

		Dim oResponse = DirectCast(oRequestProcessorProxyForDotNetClient.Process(entityRequest).First(), GetImageO)

		If oResponse.ImageByteArray IsNot Nothing Then
			If My.Computer.FileSystem.FileExists(cFILENAME) Then My.Computer.FileSystem.DeleteFile(cFILENAME)

			oFileStream = New FileStream(cFILENAME, FileMode.Create)
			oFileStream.Write(oResponse.ImageByteArray, 0, oResponse.ImageByteArray.Length)
			oFileStream.Close()

			Console.WriteLine("  Image downloaded: " + cFILENAME)
		End If

		Console.WriteLine("")
	End Sub

	' ----------------------------------------------------------------------------
	' ---------- Older Code, examples not yet updated since last changes ---------
	' ----------------------------------------------------------------------------

	' -----------------------------------------
	' ---------- Asynchronous Call ------------
	' -----------------------------------------
	'Private Sub RPProxyGetBorrowerOneRequestAsync()
	'  Console.WriteLine("Calling proxy.ProcessAsync()")

  '  configRequestProxy.ProcessAsync(AddressOf GetBorrowerOneRequestWithProxyConfigAsynCallBack, New GetBorrowerI())

  '  Console.WriteLine("End of RPProxyGetBorrowerOneRequestAsync")
  'End Sub

  '' This is the callback once the server is done processing the request
  'Private Sub GetBorrowerOneRequestWithProxyConfigAsynCallBack(ByVal responses As IList(Of Albatross.Common.Messaging.Response))

  '  Console.WriteLine("In the call back - GetBorrowerOneRequestWithProxyConfigAsynCallBack()")

  '  Dim response = DirectCast(responses(0), GetBorrowerO)

  '  Console.WriteLine("First Name: " & response.MyBorrower.FirstName.ToString())
  '  Console.WriteLine("Last Name: " & response.MyBorrower.LastName.ToString())
  '  Console.WriteLine("")
  'End Sub

  '' -----------------------------------------
  '' ----------- Custom Requests -------------
  '' -----------------------------------------
  'Private Sub RPGetBorrowerWithWrap()
  '  Dim entityRequest = New GetBorrowerWithWrapI()
  '  entityRequest.message2 = "Place values that would be relevant to all requests in your custom request."

  '  Console.WriteLine("Calling GetBorrowerWithWrapI() based on config settings")
  '  Console.WriteLine()

  '  Dim response = DirectCast(configRequestProxy.Process(entityRequest).First(), GetBorrowerO)

  '  Console.WriteLine("  First Name: " & response.MyBorrower.FirstName.ToString())
  '  Console.WriteLine("  Last Name: " & response.MyBorrower.LastName.ToString())
  '  Console.WriteLine("")
  'End Sub

  '' -------------------------------------------------------------------
  '' ----------- Multiple Requests with one call to server -------------
  '' -------------------------------------------------------------------
  'Private Sub RPGetBorrowerAndListBorrowersOneCallMultipleRequests()
  '  Dim oBorrower As Borrower
  '  Dim entityRequest = New GetBorrowerI()
  '  Dim entityRequest2 = New ListBorrowersI()

  '  Console.WriteLine("Calling GetBorrower() and ListBorrowers() with one call to the server.")
  '  Console.WriteLine()

  '  Dim responses = configRequestProxy.Process(entityRequest, entityRequest2)
  '  For i As Integer = 0 To responses.Length - 1
  '    If responses(i).[GetType]() Is GetType(GetBorrowerO) Then
  '      Dim GetBorrowerResponse As GetBorrowerO = DirectCast(responses(i), GetBorrowerO)
  '      Console.WriteLine("  First Name: " & GetBorrowerResponse.MyBorrower.FirstName.ToString())
  '      Console.WriteLine("  Last Name: " & GetBorrowerResponse.MyBorrower.LastName.ToString())
  '      Console.WriteLine("")
  '    ElseIf responses(i).[GetType]() Is GetType(ListBorrowersO) Then
  '      Dim ListBorrowersResponse As ListBorrowersO = DirectCast(responses(i), ListBorrowersO)
  '      For Each oBorrower In ListBorrowersResponse.MyBorrowers
  '        Console.WriteLine("  First Name: " & oBorrower.FirstName.ToString())
  '        Console.WriteLine("  Last Name: " & oBorrower.LastName.ToString())
  '        Console.WriteLine("")
  '      Next
  '    End If
  '  Next
  'End Sub

  '' -------------------------------------------------------------------
  '' ------------------ Server and Client Exceptions -------------------
  '' -------------------------------------------------------------------
  'Private Sub RPGetBorrowerRaiseException()
  '  ' Make sure you have a try...catch when calling server functions
  '  ' To simplify the samples we do not do this in every client function
  '  Try
  '    Dim entityRequest = New GetBorrowerRaisesExceptionI()

  '    Console.WriteLine("Calling GetBorrowerRaiseException().")
  '    Console.WriteLine()

  '    Dim response = configRequestProxy.Process(entityRequest).First()

  '    If response.StatusType <> 0 Then
  '      ' If an exception occurs on the server, Albatross sets the 
  '      'StatusCode to ErrorCode.HandlerNotFound or ErrorCode.UnHandledException
  '      Select Case response.StatusType
  '        Case CInt(ErrorType.HandlerNotFound)
  '          Console.WriteLine("Error on the server: HandlerNotFound for 'GetBorrowerRaisesExceptionI'") ' Did you forget to implement the handler on the server for this contract?
  '        Case CInt(ErrorType.RequestProcessorUnHandledException)
  '          Console.WriteLine("Error on the server: UnHandledException = " & response.StatusInfo) ' An exception occured on the server, in our example a division by zero.
  '      End Select
  '    Else
  '      Dim GetBorrowerResponse As GetBorrowerO = DirectCast(response, GetBorrowerO)
  '      Console.WriteLine("First Name: " & GetBorrowerResponse.MyBorrower.FirstName.ToString())
  '    End If
  '  Catch ex As System.Exception
  '    ' You need this to handle client exceptions (timeout, etc...)
  '    Console.WriteLine("Exception on the client: " & ex.ToString())
  '  End Try

  '  Console.WriteLine()
  'End Sub

  '' -------------------------------------------------------------------
  '' ------------------ Exception handled on Server --------------------
  '' -------------------------------------------------------------------
  'Private Sub RPGetBorrowerRaiseException2()
  '  ' Make sure you have a try...catch when calling server functions
  '  ' To simplify the samples we do not do it in every client function
  '  Try
  '    Dim entityRequest = New GetBorrowerRaisesException2I()

  '    Console.WriteLine("Calling GetBorrowerRaiseException2().")
  '    Console.WriteLine()
  '    Dim response = configRequestProxy.Process(entityRequest).First()

  '    If response.StatusType = -1 Then
  '      ' If an exception occurs on the server, in this example we handled it and set the StatusType to -1
  '      Console.WriteLine()
  '      Dim GetBorrowerResponse As GetBorrowerRaisesException2O = DirectCast(response, GetBorrowerRaisesException2O)
  '      Console.WriteLine("Exception handled on the server, Message: " & GetBorrowerResponse.ExceptionMessage)
  '    Else
  '      Console.WriteLine()
  '      Dim GetBorrowerResponse As GetBorrowerRaisesException2O = DirectCast(response, GetBorrowerRaisesException2O)
  '      Console.WriteLine("First Name: " & GetBorrowerResponse.MyBorrower.FirstName.ToString())
  '    End If
  '  Catch ex As System.Exception
  '    ' You need this to handle client exceptions (timeout, etc...)
  '    Console.WriteLine("Exception on the client: " & ex.ToString())
  '  End Try
  'End Sub

  '' ---------------------------------------------------------------
  '' ---------- Synchronous Call - very large response -------------
  '' ---------------------------------------------------------------
  'Private Sub RPGetLargeResponseRequest()
  '  Dim entityRequest = New GetLargeResponseRequestI

  '  ' 8193 nodes in XML response, over 800KB
  '  Console.WriteLine("Calling GetLargeResponseRequestRH() based on programmatically created settings")
  '  Console.WriteLine()

  '  Dim response = DirectCast(progRequestProxy.Process(entityRequest).First(), GetLargeResponseRequestO)

  '  Console.WriteLine("  String List Count : " & response.StringList.Count.ToString)
  '  Console.WriteLine("  First string : " & response.StringList(0).ToString)
  '  Console.WriteLine("")
  'End Sub

  ' These are the sample using the ChannelFactoryProxy (config or code)
  ' Another way to use Albatross, but not the recommended way (all samples may not be up to date)

  'Private Sub GetBorrowerOneRequestConfigProxy()
  '  Dim oRequest As GetBorrowerI
  '  Dim oResponses As Albatross.Common.Messaging.Response()
  '  Dim oResponse As New GetBorrowerO

  '  Console.WriteLine("Calling GetBorrower() based on config settings")
  '  Console.WriteLine()

  '  oRequest = New GetBorrowerI
  '  oRequest.BorrowerID = New Guid

  '  oResponses = configProxy.Process(oRequest)
  '  If TypeOf oResponses.First() Is GetBorrowerO Then oResponse = DirectCast(oResponses.First(), GetBorrowerO)

  '  If oResponse IsNot Nothing Then
  '    If oResponse.MyBorrower IsNot Nothing Then
  '      Console.WriteLine("  First Name: " + oResponse.MyBorrower.FirstName.ToString)
  '      Console.WriteLine("  Last Name: " + oResponse.MyBorrower.LastName.ToString)
  '    End If
  '  End If
  'End Sub

  'Private Sub GetBorrowerOneRequestCodeProxy()
  '  Dim oRequest As GetBorrowerI
  '  Dim oResponses As Albatross.Common.Messaging.Response()
  '  Dim oResponse As New GetBorrowerO

  '  Console.WriteLine()
  '  Console.WriteLine("Calling GetBorrower() based on programmatically created settings")
  '  Console.WriteLine()

  '  oRequest = New GetBorrowerI
  '  oRequest.BorrowerID = New Guid

  '  oResponses = progProxy.Process(oRequest)
  '  oResponse = DirectCast(oResponses.First(), GetBorrowerO)

  '  Console.WriteLine("  First Name: " + oResponse.MyBorrower.FirstName.ToString)
  '  Console.WriteLine("  Last Name: " + oResponse.MyBorrower.LastName.ToString)
  'End Sub

  'Private Sub GetBorrowerOneRequestWithStatusCode()
  '  Dim oRequest As GetBorrowerWithStatusCodeI
  '  Dim oResponses As Albatross.Common.Messaging.Response()
  '  Dim oResponse As New GetBorrowerWithStatusCodeO

  '  Console.WriteLine("Calling GetBorrowerWithStatusCode() based on config settings")
  '  Console.WriteLine()

  '  oRequest = New GetBorrowerWithStatusCodeI
  '  oRequest.BorrowerID = New Guid

  '  oResponses = configProxy.Process(oRequest)
  '  If TypeOf oResponses.First() Is GetBorrowerWithStatusCodeO Then oResponse = DirectCast(oResponses.First(), GetBorrowerWithStatusCodeO)

  '  If oResponse IsNot Nothing Then
  '    If oResponse.StatusCode = 1 Then ' (1 = Success)
  '      If oResponse.MyBorrower IsNot Nothing Then
  '        Console.WriteLine("  Message: " + oResponse.Message.ToString)
  '        Console.WriteLine("  First Name: " + oResponse.MyBorrower.FirstName.ToString)
  '        Console.WriteLine("  Last Name: " + oResponse.MyBorrower.LastName.ToString)
  '      End If
  '    End If
  '  End If
  'End Sub

  'Private Sub GetBorrowerRaiseException()
  '  ' Make sure you have a try...catch when calling server functions
  '  ' To simplify the samples we do not do it in every client function

  '  Try
  '    Dim entityRequest = New GetBorrowerRaisesExceptionI

  '    Console.WriteLine("Calling GetBorrowerRaiseException().")
  '    Console.WriteLine()

  '    Dim response = configProxy.Process(entityRequest).First()
  '    Dim GetBorrowerResponse As GetBorrowerO = DirectCast(response, GetBorrowerO)
  '    Console.WriteLine("First Name: " + GetBorrowerResponse.MyBorrower.FirstName.ToString)

  '  Catch ex As System.Exception
  '    Console.WriteLine("Exception: " + ex.ToString)
  '  End Try
  'End Sub

  'Private Sub GetBorrowerAndListBorrowersOneCallMultipleRequests()
  '  Dim oRequest As GetBorrowerI
  '  Dim oRequest2 As ListBorrowersI
  '  Dim oResponses As Albatross.Common.Messaging.Response()
  '  Dim oResponse As GetBorrowerO
  '  Dim oResponse2 As ListBorrowersO
  '  Dim i As Integer = 0
  '  Dim oBorrower As Borrower
  '  Dim j As Integer = 0

  '  Console.WriteLine("Calling GetBorrower() and ListBorrowers() with one call to the server.")
  '  Console.WriteLine()

  '  oRequest = New GetBorrowerI
  '  oRequest.BorrowerID = New Guid

  '  oRequest2 = New ListBorrowersI
  '  oResponses = configProxy.Process(oRequest, oRequest2)

  '  For i = 0 To oResponses.Length - 1
  '    If TypeOf oResponses(i) Is GetBorrowerO Then
  '      oResponse = DirectCast(oResponses(i), GetBorrowerO)
  '      Console.WriteLine("  First Name: " + oResponse.MyBorrower.FirstName.ToString)
  '      Console.WriteLine("  Last Name: " + oResponse.MyBorrower.LastName.ToString)
  '      Console.WriteLine()

  '    ElseIf TypeOf oResponses(i) Is ListBorrowersO Then
  '      oResponse2 = DirectCast(oResponses(i), ListBorrowersO)

  '      For Each oBorrower In oResponse2.MyBorrowers
  '        j += 1
  '        Console.WriteLine("  Borrower number " + j.ToString)

  '        Console.WriteLine("    First Name: " + oBorrower.FirstName.ToString)
  '        Console.WriteLine("    Last Name: " + oBorrower.LastName.ToString)
  '        Console.WriteLine()
  '      Next
  '    End If
  '  Next
  'End Sub

  'Public Function GetServiceProxyWithConfigFileSettings() As Albatross.Common.WCF.IWcfRequestProcessor
  '  Return New ChannelFactory(Of Albatross.Common.WCF.IWcfRequestProcessor)("WcfRequestProcessor.EndPoint").CreateChannel()
  'End Function

  'Public Function GetServiceProxyWithProgrammaticallyCreatedSettings() As Albatross.Common.WCF.IWcfRequestProcessor
  '  Dim binding = New BasicHttpBinding()
  '  Dim address = New EndpointAddress("http://localhost:9000/RequestProcessor.svc")

  '  Return New ChannelFactory(Of Albatross.Common.WCF.IWcfRequestProcessor)(binding, address).CreateChannel()
  'End Function
End Module
